/* 
 * Copyright 2014 Igor Maznitsa (http://www.igormaznitsa.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.igormaznitsa.jhexed.swing.editor.ui.frames.layers;

import com.igormaznitsa.jhexed.hexmap.HexFieldLayer;
import com.igormaznitsa.jhexed.swing.editor.ui.dialogs.EditLayerDialog;
import com.igormaznitsa.jhexed.hexmap.HexMapPanel;
import com.igormaznitsa.jhexed.hexmap.HexMapPanelListener;
import com.igormaznitsa.jhexed.swing.editor.model.*;
import com.igormaznitsa.jhexed.swing.editor.ui.frames.FrameType;
import java.awt.geom.Path2D;
import javax.swing.JOptionPane;

public class FrameLayers extends javax.swing.JInternalFrame implements InsideApplicationBus.AppBusListener, HexMapPanelListener {
  private static final long serialVersionUID = -3120809272379715966L;
  private final LayerListComponent layerList;

  private Path2D hexShape;
  private final HexMapPanel panel;
  
  public FrameLayers(final LayerListModel listModel, final HexMapPanel panel) {
    initComponents();
    
    this.panel = panel;
    
    this.layerList = new LayerListComponent(listModel);
    this.scrollLayerList.getViewport().add(this.layerList);
    
    InsideApplicationBus.getInstance().addAppBusListener(this);
  
    this.panel.addHexMapPanelListener(this);
  }

 
  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    scrollLayerList = new javax.swing.JScrollPane();
    jToolBar1 = new javax.swing.JToolBar();
    buttonLayerUp = new javax.swing.JButton();
    buttonLayerDown = new javax.swing.JButton();
    buttonAddLayer = new javax.swing.JButton();
    buttonDeleteLayer = new javax.swing.JButton();
    buttonEditLayer = new javax.swing.JButton();

    setClosable(true);
    setDefaultCloseOperation(javax.swing.WindowConstants.HIDE_ON_CLOSE);
    setResizable(true);
    setTitle("Layers");
    setToolTipText("List of layers for the current work map");
    setPreferredSize(new java.awt.Dimension(200, 400));
    addComponentListener(new java.awt.event.ComponentAdapter() {
      public void componentHidden(java.awt.event.ComponentEvent evt) {
        formComponentHidden(evt);
      }
      public void componentShown(java.awt.event.ComponentEvent evt) {
        formComponentShown(evt);
      }
    });
    getContentPane().add(scrollLayerList, java.awt.BorderLayout.CENTER);

    jToolBar1.setFloatable(false);
    jToolBar1.setRollover(true);

    buttonLayerUp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/igormaznitsa/jhexed/swing/editor/icons/navigation-090-button.png"))); // NOI18N
    buttonLayerUp.setToolTipText("Up the selected layer in the stack");
    buttonLayerUp.setFocusable(false);
    buttonLayerUp.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonLayerUp.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonLayerUp.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonLayerUpActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonLayerUp);

    buttonLayerDown.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/igormaznitsa/jhexed/swing/editor/icons/navigation-270-button.png"))); // NOI18N
    buttonLayerDown.setToolTipText("Down the selected layer in the stack");
    buttonLayerDown.setFocusable(false);
    buttonLayerDown.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonLayerDown.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonLayerDown.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonLayerDownActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonLayerDown);

    buttonAddLayer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/igormaznitsa/jhexed/swing/editor/icons/plus-button.png"))); // NOI18N
    buttonAddLayer.setToolTipText("Add new layer");
    buttonAddLayer.setFocusable(false);
    buttonAddLayer.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonAddLayer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonAddLayer.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonAddLayerActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonAddLayer);

    buttonDeleteLayer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/igormaznitsa/jhexed/swing/editor/icons/minus-button.png"))); // NOI18N
    buttonDeleteLayer.setToolTipText("Delete the selected layer");
    buttonDeleteLayer.setFocusable(false);
    buttonDeleteLayer.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonDeleteLayer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonDeleteLayer.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonDeleteLayerActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonDeleteLayer);

    buttonEditLayer.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/igormaznitsa/jhexed/swing/editor/icons/edit-image.png"))); // NOI18N
    buttonEditLayer.setToolTipText("Edit the selected layer");
    buttonEditLayer.setFocusable(false);
    buttonEditLayer.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonEditLayer.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonEditLayer.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonEditLayerActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonEditLayer);

    getContentPane().add(jToolBar1, java.awt.BorderLayout.PAGE_START);

    pack();
  }// </editor-fold>//GEN-END:initComponents

  private void formComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentShown
    InsideApplicationBus.getInstance().fireEvent(this, InsideApplicationBus.AppBusEvent.A_FRAME_CHANGED_ITS_STATUS, this, FrameType.LAYERS);
  }//GEN-LAST:event_formComponentShown

  private void formComponentHidden(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentHidden
    InsideApplicationBus.getInstance().fireEvent(this, InsideApplicationBus.AppBusEvent.A_FRAME_CHANGED_ITS_STATUS, this, FrameType.LAYERS);
  }//GEN-LAST:event_formComponentHidden

  private void buttonAddLayerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonAddLayerActionPerformed
    InsideApplicationBus.getInstance().fireEvent(this, InsideApplicationBus.AppBusEvent.REQUEST_EVENT, InsideApplicationBus.AppBusEvent.HEX_SHAPE);
    
    final EditLayerDialog dlg = new EditLayerDialog(null, (LayerListModel) this.layerList.getModel(), null, this.hexShape);
    dlg.setVisible(true);
    
    final HexFieldLayer newLayer = dlg.getResult();
    if (newLayer!=null){
      this.layerList.clearSelection();
      ((LayerListModel) this.layerList.getModel()).addLayer(newLayer);
      newLayer.updatePrerasterizedIcons(this.hexShape);
    }

  }//GEN-LAST:event_buttonAddLayerActionPerformed

  private void buttonLayerUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonLayerUpActionPerformed
    if (this.layerList.up()){
      InsideApplicationBus.getInstance().fireEvent(this, InsideApplicationBus.AppBusEvent.HEX_FIELD_NEEDS_REPAINT);
    }
  }//GEN-LAST:event_buttonLayerUpActionPerformed

  private void buttonLayerDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonLayerDownActionPerformed
    if (this.layerList.down()){
      InsideApplicationBus.getInstance().fireEvent(this, InsideApplicationBus.AppBusEvent.HEX_FIELD_NEEDS_REPAINT);
    }
  }//GEN-LAST:event_buttonLayerDownActionPerformed

  private void buttonDeleteLayerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDeleteLayerActionPerformed
    final LayerRecordPanel panel = this.layerList.getSelectedValue();
    if (panel!=null){
      if (JOptionPane.showConfirmDialog(null, "Do you really want to remove '"+panel.getLayer().getLayerName()+'\'',"Delete layer",JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION){
        this.layerList.delete(panel.getLayer());
        this.layerList.clearSelection();
        InsideApplicationBus.getInstance().fireEvent(this, InsideApplicationBus.AppBusEvent.SELECTED_LAYER_CHANGED,(Object)null);
        InsideApplicationBus.getInstance().fireEvent(this, InsideApplicationBus.AppBusEvent.HEX_FIELD_NEEDS_REPAINT);
      }
    }
  }//GEN-LAST:event_buttonDeleteLayerActionPerformed

  private void buttonEditLayerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonEditLayerActionPerformed
    final LayerRecordPanel panel = this.layerList.getSelectedValue();
    if (panel!=null){
      InsideApplicationBus.getInstance().fireEvent(this, InsideApplicationBus.AppBusEvent.LAYER_NEEDS_EDITION, panel);
    }
  }//GEN-LAST:event_buttonEditLayerActionPerformed


  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton buttonAddLayer;
  private javax.swing.JButton buttonDeleteLayer;
  private javax.swing.JButton buttonEditLayer;
  private javax.swing.JButton buttonLayerDown;
  private javax.swing.JButton buttonLayerUp;
  private javax.swing.JToolBar jToolBar1;
  private javax.swing.JScrollPane scrollLayerList;
  // End of variables declaration//GEN-END:variables



  @Override
  public void onAppBusEvent(final Object source, final InsideApplicationBus bus, final InsideApplicationBus.AppBusEvent event, final Object... objects) {
    switch(event){
      case REQUEST_EVENT: {
        if (objects[0] == InsideApplicationBus.AppBusEvent.SELECTED_LAYER_CHANGED){
          final LayerRecordPanel selected = this.layerList.getSelectedValue();
          InsideApplicationBus.getInstance().fireEvent(this, InsideApplicationBus.AppBusEvent.SELECTED_LAYER_CHANGED, selected == null ? null : selected.getLayer());
        }
      }break;
      case HEX_SHAPE : {
        this.hexShape = (Path2D)objects[0];
        for(int i=0;i<this.layerList.getModel().getSize();i++){
          this.layerList.getModel().getElementAt(i).getLayer().updatePrerasterizedIcons(this.hexShape);
        }
      }break;
    }
  }

  @Override
  public void onZoomChanged(final HexMapPanel source, final float scale) {
    for (int i=0; i< this.layerList.getModel().getSize(); i++){
      final LayerRecordPanel p = this.layerList.getModel().getElementAt(i);
      p.getLayer().updatePrerasterizedIcons(source.getHexShape());
    }
  }
}
